home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.001 / tcpdump-~ / tcpdump-3.0.2-linux / libpcap-0.0.6 / nametoaddr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-21  |  7.1 KB  |  358 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * Name to id translation routines used by the scanner.
  22.  * These functions are not time critical.
  23.  */
  24.  
  25. #ifndef lint
  26. static char rcsid[] =
  27.     "@(#) $Header: nametoaddr.c,v 1.21 94/06/20 19:07:54 leres Exp $ (LBL)";
  28. #endif
  29.  
  30. #include <sys/param.h>
  31. #include <sys/socket.h>
  32. #include <net/if.h>
  33. #include <netinet/in.h>
  34. #include <netinet/if_ether.h>
  35. #include <arpa/inet.h>
  36.  
  37. #include <ctype.h>
  38. #include <errno.h>
  39. #include <netdb.h>
  40. #include <pcap.h>
  41. #include <pcap-namedb.h>
  42. #include <stdio.h>
  43.  
  44. #include "gencode.h"
  45.  
  46. #ifndef __GNUC__
  47. #define inline
  48. #endif
  49.  
  50. #ifndef NTOHL
  51. #define NTOHL(x) (x) = ntohl(x)
  52. #define NTOHS(x) (x) = ntohs(x)
  53. #endif
  54.  
  55. static inline int xdtoi(int);
  56.  
  57. /*
  58.  *  Convert host name to internet address.
  59.  *  Return 0 upon failure.
  60.  */
  61. u_long **
  62. pcap_nametoaddr(const char *name)
  63. {
  64. #ifndef h_addr
  65.     static u_long *hlist[2];
  66. #endif
  67.     u_long **p;
  68.     struct hostent *hp;
  69.  
  70.     if ((hp = gethostbyname(name)) != NULL) {
  71. #ifndef h_addr
  72.         hlist[0] = (u_long *)hp->h_addr;
  73.         NTOHL(hp->h_addr);
  74.         return hlist;
  75. #else
  76.         for (p = (u_long **)hp->h_addr_list; *p; ++p)
  77.             NTOHL(**p);
  78.         return (u_long **)hp->h_addr_list;
  79. #endif
  80.     }
  81.     else
  82.         return 0;
  83. }
  84.  
  85. /*
  86.  *  Convert net name to internet address.
  87.  *  Return 0 upon failure.
  88.  */
  89. u_long
  90. pcap_nametonetaddr(const char *name)
  91. {
  92.     struct netent *np;
  93.  
  94.     if ((np = getnetbyname(name)) != NULL)
  95.         return np->n_net;
  96.     else
  97.         return 0;
  98. }
  99.  
  100. /*
  101.  * Convert a port name to its port and protocol numbers.
  102.  * We assume only TCP or UDP.
  103.  * Return 0 upon failure.
  104.  */
  105. int
  106. pcap_nametoport(const char *name, int *port, int *proto)
  107. {
  108.     struct servent *sp;
  109.     char *other;
  110.  
  111.     sp = getservbyname(name, (char *)0);
  112.     if (sp != NULL) {
  113.         NTOHS(sp->s_port);
  114.         *port = sp->s_port;
  115.         *proto = pcap_nametoproto(sp->s_proto);
  116.         /*
  117.          * We need to check /etc/services for ambiguous entries.
  118.          * If we find the ambiguous entry, and it has the
  119.          * same port number, change the proto to PROTO_UNDEF
  120.          * so both TCP and UDP will be checked.
  121.          */
  122.         if (*proto == IPPROTO_TCP)
  123.             other = "udp";
  124.         else
  125.             other = "tcp";
  126.  
  127.         sp = getservbyname(name, other);
  128.         if (sp != 0) {
  129.             NTOHS(sp->s_port);
  130.             if (*port != sp->s_port)
  131.                 /* Can't handle ambiguous names that refer
  132.                    to different port numbers. */
  133. #ifdef notdef
  134.                 warning("ambiguous port %s in /etc/services",
  135.                     name);
  136. #else
  137.             ;
  138. #endif
  139.             *proto = PROTO_UNDEF;
  140.         }
  141.         return 1;
  142.     }
  143. #if defined(ultrix) || defined(__osf__)
  144.     /* Special hack in case NFS isn't in /etc/services */
  145.     if (strcmp(name, "nfs") == 0) {
  146.         *port = 2049;
  147.         *proto = PROTO_UNDEF;
  148.         return 1;
  149.     }
  150. #endif
  151.     return 0;
  152. }
  153.  
  154. int
  155. pcap_nametoproto(const char *str)
  156. {
  157.     struct protoent *p;
  158.  
  159.     p = getprotobyname(str);
  160.     if (p != 0)
  161.         return p->p_proto;
  162.     else
  163.         return PROTO_UNDEF;
  164. }
  165.  
  166. #include "ethertype.h"
  167.  
  168. struct eproto {
  169.     char *s;
  170.     u_short p;
  171. };
  172.  
  173. /* Static data base of ether protocol types. */
  174. struct eproto eproto_db[] = {
  175.     { "pup", ETHERTYPE_PUP },
  176.     { "xns", ETHERTYPE_NS },
  177.     { "ip", ETHERTYPE_IP },
  178.     { "arp", ETHERTYPE_ARP },
  179.     { "rarp", ETHERTYPE_REVARP },
  180.     { "sprite", ETHERTYPE_SPRITE },
  181.     { "mopdl", ETHERTYPE_MOPDL },
  182.     { "moprc", ETHERTYPE_MOPRC },
  183.     { "decnet", ETHERTYPE_DN },
  184.     { "lat", ETHERTYPE_LAT },
  185.     { "lanbridge", ETHERTYPE_LANBRIDGE },
  186.     { "vexp", ETHERTYPE_VEXP },
  187.     { "vprod", ETHERTYPE_VPROD },
  188.     { "atalk", ETHERTYPE_ATALK },
  189.     { "atalkarp", ETHERTYPE_AARP },
  190.     { "loopback", ETHERTYPE_LOOPBACK },
  191.     { "decdts", ETHERTYPE_DECDTS },
  192.     { "decdns", ETHERTYPE_DECDNS },
  193.     { (char *)0, 0 }
  194. };
  195.  
  196. int
  197. pcap_nametoeproto(const char *s)
  198. {
  199.     struct eproto *p = eproto_db;
  200.  
  201.     while (p->s != 0) {
  202.         if (strcmp(p->s, s) == 0)
  203.             return p->p;
  204.         p += 1;
  205.     }
  206.     return PROTO_UNDEF;
  207. }
  208.  
  209. /* Hex digit to integer. */
  210. static inline int
  211. xdtoi(c)
  212.     register int c;
  213. {
  214.     if (isdigit(c))
  215.         return c - '0';
  216.     else if (islower(c))
  217.         return c - 'a' + 10;
  218.     else
  219.         return c - 'A' + 10;
  220. }
  221.  
  222. u_long
  223. __pcap_atoin(const char *s)
  224. {
  225.     u_long addr = 0;
  226.     u_int n;
  227.  
  228.     while (1) {
  229.         n = 0;
  230.         while (*s && *s != '.')
  231.             n = n * 10 + *s++ - '0';
  232.         addr <<= 8;
  233.         addr |= n & 0xff;
  234.         if (*s == '\0')
  235.             return addr;
  236.         ++s;
  237.     }
  238.     /* NOTREACHED */
  239. }
  240.  
  241. u_long
  242. __pcap_atodn(const char *s)
  243. {
  244. #define AREASHIFT 10
  245. #define AREAMASK 0176000
  246. #define NODEMASK 01777
  247.  
  248.     u_long addr = 0;
  249.     u_int node, area;
  250.  
  251.     if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
  252.         bpf_error("malformed decnet address '%s'", s);
  253.  
  254.     addr = (area << AREASHIFT) & AREAMASK;
  255.     addr |= (node & NODEMASK);
  256.  
  257.     return(addr);
  258. }
  259.  
  260. /*
  261.  * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
  262.  * ethernet address.  Assumes 's' is well formed.
  263.  */
  264. u_char *
  265. pcap_ether_aton(const char *s)
  266. {
  267.     register u_char *ep, *e;
  268.     register u_int d;
  269.  
  270.     e = ep = (u_char *)malloc(6);
  271.  
  272.     while (*s) {
  273.         if (*s == ':')
  274.             s += 1;
  275.         d = xdtoi(*s++);
  276.         if (isxdigit(*s)) {
  277.             d <<= 4;
  278.             d |= xdtoi(*s++);
  279.         }
  280.         *ep++ = d;
  281.     }
  282.  
  283.     return (e);
  284. }
  285.  
  286. #ifndef ETHER_SERVICE
  287. /* Roll our own */
  288. u_char *
  289. pcap_ether_hostton(const char *name)
  290. {
  291.     register struct pcap_etherent *ep;
  292.     register u_char *ap;
  293.     static FILE *fp = NULL;
  294.     static init = 0;
  295.  
  296.     if (!init) {
  297.         fp = fopen(PCAP_ETHERS_FILE, "r");
  298.         ++init;
  299.         if (fp == NULL)
  300.             return (NULL);
  301.     } else if (fp == NULL)
  302.         return (NULL);
  303.     else
  304.         rewind(fp);
  305.     
  306.     while ((ep = pcap_next_etherent(fp)) != NULL) {
  307.         if (strcmp(ep->name, name) == 0) {
  308.             ap = (u_char *)malloc(6);
  309.             if (ap != NULL) {
  310.                 memcpy(ap, ep->addr, 6);
  311.                 return (ap);
  312.             }
  313.             break;
  314.         }
  315.     }
  316.     return (NULL);
  317. }
  318. #else
  319. /* Use the os supplied routines */
  320. u_char *
  321. pcap_ether_hostton(const char *name)
  322. {
  323.     register u_char *ap;
  324.     u_char a[6];
  325. #ifndef sgi
  326.     extern int ether_hostton(char *, struct ether_addr *);
  327. #endif
  328.  
  329.     ap = NULL;
  330.     if (ether_hostton((char*)name, (struct ether_addr *)a) == 0) {
  331.         ap = (u_char *)malloc(6);
  332.         if (ap != NULL)
  333.             memcpy(ap, a, 6);
  334.     }
  335.     return (ap);
  336. }
  337. #endif
  338.  
  339. u_short
  340. __pcap_nametodnaddr(const char *name)
  341. {
  342. #ifdef    DECNETLIB
  343.     struct nodeent *getnodebyname();
  344.     struct nodeent *nep;
  345.     unsigned short res;
  346.  
  347.     nep = getnodebyname(name);
  348.     if (nep == ((struct nodeent *)0))
  349.         bpf_error("unknown decnet host name '%s'\n", name);
  350.  
  351.     memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
  352.     return(res);
  353. #else
  354.     bpf_error("decnet name support not included, '%s' cannot be translated\n",
  355.         name);
  356. #endif
  357. }
  358.